#ifndef _BOUNDING_VOLUME_H_
#define _BOUNDING_VOLUME_H_
#include "DataStructure.h"
// Aabb ( axis aligned bounding box )
// Properties :
//		minVertex	: Vertex with lowest xyz
//		maxVertex : Vertex with highest xyz
//			_________
//		   /| 	    /|
//		  / |	   / |					^ y
//		 /__|__max/	 |					|
//		|   |	  |	 |					|
//		|   |_____|__|                  |----> x
//		|  /min   |  /				   /
//		| /		  | /			      /
//		|/________|/				 < z
//
class gewAabb
{
public:
	gewVec3 minVertex;
    gewVec3 maxVertex;
    char      outerPlane;
	// Defaut Constructor
	// Description :
	//		Create a Aabb with default minVertex (0,0,0) and default maxVertex(0,0,0)
	gewAabb();
	// Constructor 
	gewAabb( gewVec3 minVertex,
			gewVec3 maxVertex);
	// Constructor
	gewAabb( float minX,
		  float minY,
		  float minZ,
		  float maxX,
		  float maxY,
		  float maxZ );
	// Destructor
	~gewAabb();
	// repair()
	// Description :
	// Check for error between minVertex and maxVertex and repair				
    void repair();
	// addInternalPoint(..)
	// Parameter :
	//		x,y,z : define the point
	// Description :
	//		This function calculate new box that contain current box and the point (x,y,z)
	void addInternalPoint(float x, 
						  float y, 
						  float z);
	void addInternalPoint(gewVec3& point);
	// addInternalBox(..)
	// Parameter :
	//		add_box : an aabb;
	// Description :
	//		This function calculate new box that contain current box and the add_box
	void addInternalBox(gewAabb& add_box);

	// getVertexList(..)
	// Parameter :
	//		vertex_array : pointer to buffer ( size must be > 8*3* sizeof( _type) )
	// Description :
	//		This function fill vertex_array with this AABB vertex info as below :
	//			{v0.x, v0.y,v0.z,v1.x,v2.y,v3.z,...,v8.x,v8.y,v8.z}
	//			
	//		 	_________
	//		   /|7 	    /|6
	//		  / |	   / |					^ y
	//		4/__|___ 5/	 |					|
	//		|   |	  |	 |					|
	//		|   |_____|__|1                 |----> x
	//		|  /0     |  /				   /
	//		| /		  | /				  /
	//		|/3_______|2				 < z
	//
	//void getVertexList(gewVec3* vertex_array) const;

//// isContain(..)
//// Parameter :
////			_point : a point
//// Description :
////		Return the correlate of this box and point _point 
////					Return EI_OUT if _point's outside this box
////					Return EI_IN	 if _point's inside  this box
//E_INTERSECTION isContain(vector_t& _point);
//// isContain(..)
//// Parameter :
////			_box : a box
//// Description :
////		Return the correlate of this box and box _box 
////					Return EI_OUT if _box's outside this box
////					Return EI_IN	 if _box's inside  this box
////					Return EI_INTERSECT if _box intersect with this box
////					Return EI_INTERNAL  if thix box's inside _box
//E_INTERSECTION isContain(Aabb& _box);
//
//E_INTERSECTION isIntersectionWithLineSegment( const vector_t point1,
//																							const vector_t point2,
//																							vector_t& intersect1,
//																							vector_t& intersect2) const;
	// isValid()
	// Description :
	//		Return this box's a valid box or not ( maxVertex > min Vertex)
	bool isValid();
};

// Sphere
// Properties :
//		center : the center point of this sphere
//		radius : radius of this sphere
// Description :
//		Sphere's used to specify the volume bounding of an Scenenode
class gewSphere
{
public:
	gewVec3	center;
	float radius;
	char outerPlane;
	// Default constructor
	// Description :
	//		Default value is : center(0,0,0), radius(1.0)
	gewSphere();
	// Constructor
	// Description :
	//		Create a sphere with center = _center , radius = _radius
	gewSphere( gewVec3 _center,float _radius);
	// Constructor
	// Parameter :
	//		box : an axis aligned bounding box
	// Description :
	//		Create a sphere that contain the box
	//				center = (box.minVertex + box.maxVertex) /2
	//				radus	 = length( box.center - box.minVertex)
	gewSphere(gewAabb& box);
	// addInternalPoint(..)
	// Parameter :
	//		x,y,z : define the point
	// Description :
	//		This function re-calculate this sphere to make it contain current sphere and the point (x,y,z)
	void addInternalPoint(float x, 
						  float y, 
						  float z);
	void addInternalPoint(gewVec3& point);
	
	// addInternalSphere(..)
	// Parameter :
	//		_sphere : a sphere
	// Description :
	//		This function re-calculate this sphere to make it contain current sphere and the Sphere _sphere
	//void addInternalSphere(gewSphere& _sphere);
	
	// calculate(..)
	// Parameter :
	//			vertex_list : an float_t array
	//			num : size of vertex_list array
	// Description :
	//			This function re-calculate this sphere to make it contain all vertices in vertex_list 										
	void calculate(float *vertex_list,int num);
	void calculate(arrayVec3 vertices);
	//// isContain(..)
	//// Parameter :
	////			_point : a point
	//// Description :
	////		Return the correlate of this sphere and point _point 
	////					Return EI_OUT if _point's outside this sphere
	////					Return EI_IN	 if _point's inside  this sphere
	//E_INTERSECTION isContain(vector_t& _point);
	//// isContain(..)
	//// Parameter :
	////			_box : a box
	//// Description :
	////		Return the correlate of this Sphere and Sphere _sphere 
	////					Return EI_OUT if _sphere's outside this Sphere
	////					Return EI_IN	 if _sphere's inside  this Sphere
	////					Return EI_INTERSECT if _sphere intersect with this Sphere
	////					Return EI_INTERNAL	 if this sphere inside _sphere
	//E_INTERSECTION isContain(Sphere& _sphere);
	//
	//// isValid()
	//// Description :
	////		Return this Sphere's a valid Sphere or not ( radius >0 )
	inline bool isValid(){ return radius >0;}
};

#endif